package com.deng.eventflow.core.functions;

import com.deng.eventflow.core.Context;
import com.deng.eventflow.core.EventTracker;
import com.deng.eventflow.core.exception.Variant;

import java.util.Set;

public class IdentityFunction extends Function {
    /**
     * The input arity of the function (which is also its output arity)
     */
    protected int m_inArity = 1;

    /**
     * Creates a new identity function
     *
     * @param arity
     *          The arity of the function
     */
    public IdentityFunction(int arity)
    {
        super();
        m_inArity = arity;
    }

    @Override
    public void evaluate(Object[] inputs, Object[] outputs, Context context, EventTracker tracker)
    {
        for (int i = 0; i < inputs.length; i++)
        {
            outputs[i] = inputs[i];
            if (tracker != null)
            {
                tracker.associateToOutput(-1, i, 0, i, 0);
            }
        }
    }

    @Override
    public void evaluate(Object[] inputs, Object[] outputs)
    {
        evaluate(inputs, outputs, null);
    }

    @Override
    public int getInputArity()
    {
        return m_inArity;
    }

    @Override
    public int getOutputArity()
    {
        return m_inArity;
    }

    @Override
    public void reset()
    {
        // Nothing to do
    }

    @Override
    public IdentityFunction duplicate(boolean with_state) {
        return new IdentityFunction(m_inArity);
    }

    @Override
    public void getInputTypesFor(Set<Class<?>> classes, int index) {
        classes.add(Variant.class);
    }

    @Override
    public Class<?> getOutputTypeFor(int index) {
        return Variant.class;
    }

    /**
     * @since 0.10.2
     */
    @Override
    public Object printState() {
        return m_inArity;
    }

    /**
     * @since 0.10.2
     */
    @Override
    public IdentityFunction readState(Object o) {
        return new IdentityFunction(((Number) o).intValue());
    }
}
